home *** CD-ROM | disk | FTP | other *** search
- /* Autotest.C - Test raw disk I/O - Nov. 84 PC Tech Journal pp 64-70 */
- /* Modified for DeSmet C - H.G.Williams */
-
- #include "stdio.h"
-
- #define ASIZE 25000 /* size of buffer area */
-
- long seqio() , randio() ;
- long gettime() ;
- char *align() ;
- int dno , nstart , i ,nit ;
- char *pbuf ;
-
- int clu , cfree , tot , bps ; /* disk space variables */
- long totsec ; /* total sectors */
-
- main(argc,argv)
- int argc ;
- char *argv ;
- {
- char area[ASIZE] ;
-
- /* ensure that buffer does not cross a 64K address boundry */
-
- pbuf = align(area,ASIZE/2) ;
-
- printf("\n Drive No. (0 = A , 1 = B , ...): ") ;
- scanf("%d" , &dno) ;
-
- clu = getspac(dno+1 , &cfree , &tot , &bps) ;
- if (clu == 0xffff)
- {
- printf("\n Invalid Drive Number \n") ;
- exit(10) ;
- }
-
- totsec = clu * (long) tot ;
- printf("\n Total Number Of Sectors = %1u \n" , totsec) ;
-
- nstart = 0 ;
- nit = 20 ;
- printf("\n Sequential Reads \n") ;
- doseg( 1) ; /* sequential read tests */
- doseg( 8) ;
- doseg(16) ;
- doseg(24) ;
-
- nit = 40 ;
- printf("\n Random Reads - %2d Sector \n" , 1) ;
- dorand(1 , 0.10) ;
- dorand(1 , 0.33) ; /* random read tests */
- dorand(1 , 0.50) ;
- dorand(1 , 0.90) ;
-
- nit = 20 ;
- printf("\n Random Reads = %2d Sector \n" , 8) ;
- dorand(8 , 0.10) ;
- dorand(8 , 0.33) ;
- dorand(8 , 0.50) ;
- dorand(8 , 0.90) ;
-
- }
-
- int doseg(nseg)
- int nseg ;
- {
- long t ;
-
- t = seqio(dno,nseg,nstart,pbuf,nit) ;
- printf(" %2d Sectors - " , nseg) ;
- printf(" %4.3f Sec/Read \n" , t/(18.2*nit)) ;
- }
-
- int dorand(nseg,frac)
- int nseg ;
- float frac ;
- {
- long t ;
- int offset ;
-
- offset = totsec * frac ;
- t = randio(dno,nseg,nstart,pbuf,nit,offset) ;
- printf(" %5.2f Width Seeks - " , frac) ;
- printf(" %4.3f Sec/Read \n" , t/(18.2*nit)) ;
- }
-
- /* seqio.c - do a sequential io test */
-
- long seqio(dno,nseg,nstart,buffer,nit)
- int dno , nstart , nseg , nit ;
- char *buffer ;
- {
- int i , nerror ;
- long t ;
-
- nerror = 0 ;
-
- /* do one read to fix starting point */
-
- if(rawread(dno,1,nstart,buffer) != 0)
- nerror = nerror + 1 ;
-
- /* now do a series of reads */
-
- t = gettime() ; /* start timing */
- for(i=0 ; i<nit ; i=i+1)
- { /* read and check for errors */
- if(rawread(dno,nseg,nstart,buffer) != 0)
- nerror = nerror + 1 ;
- nstart = nstart + nseg ; /* move past area read */
- }
-
- t = gettime() - t ; /* get elapsed time */
- if(t <= 0L)
- t = t+0x1800B0 ;
-
- if(nerror > 0)
- printf(" %d errors \n" , nerror) ;
-
- return(t) ; /* return elapsed time in ticks */
- }
-
- /* randio.c - test random raw disk i/o */
-
- long randio(dno,nseg,nstart,buffer,nit,offset)
- int dno , nstart , nseg , nit ;
- char *buffer ;
- int offset ;
- {
- int i , nerror ;
- long t ;
-
- nerror = 0 ;
- /* do a read in second area to start */
-
- if(rawread(dno,nseg,nstart+offset,buffer) != 0)
- nerror = nerror + 1 ;
-
- t = gettime() ; /* start timing */
-
- for(i=0 ; i < (nit/2) ; i=i+1)
- { /* read first area */
- if(rawread(dno,nseg,nstart,buffer) != 0)
- nerror = nerror + 1 ;
- /* read second area */
- if(rawread(dno,nseg,nstart+offset,buffer) != 0)
- nerror = nerror + 1 ;
- nstart = nstart + nseg ;
- }
-
- t = gettime() - t ;
- if(t < 0L)
- t = t + 0x1800B0 ;
-
- if(nerror > 0)
- printf(" %d errors \n" , nerror) ;
-
- return(t) ;
- }
-
- /* align.c - align a buffer so that it does not cross a 64K boundry */
- /* Given the address of a buffer area it returns a starting address */
- /* such that the following (size) bytes do not cross a 64K byte */
- /* address boundry. */
-
- unsigned get_ds() ;
-
- char *align(area,size) /* align buffer address */
- char *area ; /* start of buffer area */
- int size ; /* size required for buffer */
-
- {
- long begin ; /* flat address for area */
- unsigned room ; /* number of bytes to boundry */
-
- /* build flat address */
-
- begin = ((long) get_ds()) * 16L + (long) area ;
-
- /* get distance to boundry */
-
- room = 0x10000 - (begin & 0xffff) ;
- if (room >= size)
- return(area) ;
- else return(area+room) ;
- }
-
- dummy()
- {
- #asm
-
- ; assembler functions for disk i/o performance benchmark
- ;
- ; rawread(drive,nsec,begin_sec,buffer) - reads raw disk sectors
- ; drive = drive number 0=A , 1=B , .....
- ; nsec = number of 512 byte sectors to read
- ; begin_sec = number of first logical sector to read
- ; buffer = store the data here (relative to ds)
-
- cseg
- public rawread,rawread_,_rawread
-
- ; define the argument offsets relative to BP
- ; old BP value is at zero
- ; return address is at 2
-
- drive equ 4
- nsec equ 6
- begsec equ 8
- buffer equ 10
-
- rawread:
- rawread_:
- _rawread: push bp
- mov bp,sp
- push bx
- push cx
- push dx
- push si
- push di
- mov ax,word [bp+drive]
- mov cx,word [bp+nsec]
- mov dx,word [bp+begsec]
- mov bx,word [bp+buffer]
- int 25H ; absolute disk read
- pop cx ; discard original flags
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- jc raw1 ; did the operation succeed ?
- mov ax,0 ; yes - set ax to 0
- jmp raw2
- raw1: ; no - force ax to be non-zero
- or ax,ax ; is ax already non-zero ?
- jnz raw2 ; yes - just use it as an error return
- mov ax,255 ; no - fake a non-zero error return
- raw2:
- pop bp
- ret
-
- ; get_ds() - returns the data segment register
-
- public get_ds,get_ds_,_get_ds
-
- get_ds:
- get_ds_:
- _get_ds:
- mov ax,ds
- ret
-
- ; long gettime() - returns time
-
- public gettime,gettime_,_gettime
-
- gettime:
- gettime_:
- _gettime:
- push cx
- push dx
- mov ax,0 ; read clock function
- int 1AH ; time-of-day BIOS call
-
- ; set up long return (dx high, ax low)
-
- mov ax,dx
- mov dx,cx
- pop dx
- pop cx
- ret
-
- ; getspac(ddrive,pfree,ptot,pbytes) - get disk free space info
- ; ddrive = drive number 0=A , 1=B .......
- ; pfree = number of free clusters
- ; ptot = total number of clusters
- ; pbytes = number of bytes per sector
- ; returns number of sectors per cluster - 0xFFFF for invalid drive
-
- ; define argument offsets
- ; old BP = 0
- ; return address = 2
-
- ddrive equ 4
- pfree equ 6
- ptot equ 8
- pbytes equ 10
-
- public getspac,getspac_,_getspac
-
- getspac:
- getspac_:
- _getspac:
- push bp
- mov bp,sp
- push bx
- push cx
- push dx
- push si
- mov dx,word [bp+ddrive]
- mov ah,36H ; DOS get free space call
- int 21H
- mov si,word [bp+pfree] ; free clusters
- mov word [si],bx
- mov si,word [bp+ptot] ; total clusters
- mov word [si],dx
- mov si,word [bp+pbytes] ; bytes per sector
- mov word [si],cx
- ; sectors per cluster already in ax
-
- ; restore registers
-
- pop si
- pop dx
- pop cx
- pop dx
- pop bp
- ret
- #
- }